package com.chaos.gateway.config.filter;

import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.security.core.context.ReactiveSecurityContextHolder;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.Map;

@Component
public class JwtToHeaderGlobalFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        return ReactiveSecurityContextHolder.getContext()
                .map(context -> context.getAuthentication())
                .filter(authentication -> authentication.getCredentials() instanceof Jwt)
                .map(authentication -> (Jwt) authentication.getCredentials())
                .flatMap(jwt -> {
                    Map<String, Object> claims = jwt.getClaims();

                    // 提取 userId 和 tenantId
                    Object userId = claims.get("userId");
                    Object userInfoId = claims.get("userInfoId");
                    Object adminId = claims.get("adminId");
                    Object tenantId = claims.get("tenantId");

                    ServerHttpRequest.Builder requestBuilder = exchange.getRequest().mutate();

                    if (userId != null) {
                        requestBuilder.header("X-User-Id", userId.toString());
                    }
                    if (userInfoId != null) {
                        requestBuilder.header("X-User-Info-Id", userInfoId.toString());
                    }
                    if (adminId != null) {
                        requestBuilder.header("X-Admin-Id", adminId.toString());
                    }
                    if (tenantId != null) {
                        requestBuilder.header("X-Tenant-Id", tenantId.toString());
                    }

                    return chain.filter(exchange.mutate().request(requestBuilder.build()).build());
                })
                .switchIfEmpty(chain.filter(exchange));
    }

    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE;
    }
}
